package com.aktk.gameelements;

import com.aktk.gameelements.GamePlay.Orientation;
import com.aktk.gameelements.GamePlay.SegmentType;

public class Ship {

	Segment segs[];
	int length;						// The number of ship segments
	Orientation orientation;
	boolean sunk;					// Ship is sunk if each segment is damaged
	boolean used;

	// Default Constructor
	public Ship( int l ) {
		length = l;
		used = false;
	}
	
	public Ship( int bowRow , int bowCol , int l , Orientation o ) {
		length = l;
		orientation = o;
		sunk = false;
		used = true;
		
		// Initializing Segment elements 
		segs = new Segment [ length ];
		for( int a = 0 ; a < length ; ++a )
		{
			if( o == Orientation.HORIZONTAL )
			{
				segs[a] = new Segment( bowRow , bowCol + a);
			}
			if( o == Orientation.VERTICAL )
			{
				segs[a] = new Segment( bowRow + a, bowCol );
			}
			segs[a].type = SegmentType.MID;
		}	
		segs[0].type = SegmentType.BOW;
		segs[length - 1].type = SegmentType.STERN;
	}
	
	public int getLength() {
		return length;
	}
	
	public Orientation getOrientation() {
		return orientation;
	}
	
	public boolean getUsed() {
		return used;
	}
		
	// Checks if the ship contains a segment at the specified coordinates
	private int contains( int row , int col ) {
		for( int a = 0 ; a < length ; ++a )
		{
			if( segs[a].isMatch( row, col) )
			{
				return a;
			}
		}
		return -1;
	}
	
	public int getRow( int segNum) {
		if ( segNum < length )
		{
			return segs[segNum].rowLocation;//
		}
		else 
		{
			return -1;
		}
	}
	
	public int getCol( int segNum) {
		if ( segNum < length )
		{
			return segs[segNum].colLocation;//
		}
		else 
		{
			return -1;
		}
	}
	
	public boolean isOverlap( Ship other) {
		for( int a = 0 ; a < length ; ++a )
		{
			for( int b = 0 ; b < other.getLength() ; ++b)
			{
				if( getRow(a) == other.getRow(b) && getCol(a) == other.getCol(b) )
				{
					return true;
				}
			}
		}
		return false;
	}
		
	// If ship contains segment, sets damage and returns true, else false
	public boolean setHit( int row , int col ) {
		int seg = contains( row , col );
		if( seg > -1 )
		{
			segs[seg].setHit();
			checkSunk();
			return true;
		}
		return false;
	}
	
	public boolean getHit( int segNum ) {
		if( segs[segNum].isHit() )
		{
			return true;
		}
		return false;
	}
		
	// Checks if ship is sunk and updates field value
	private void checkSunk()
	{
		for( int a = 0 ; a < length ; ++a )
		{
			if( segs[a].isHit() == false )
			{
				return;
			}
		}
		sunk = true;
	}
		
	// Returns whether ship is sunk
	public boolean isSunk()
	{
		return sunk;
	}
	
	public SegmentType getShipSegmentType( int segNum ){
		if( segNum == 0 )
		{
			if( length > 1 )
			{
				return SegmentType.BOW;
			}
			else
			{
				return SegmentType.WHOLE;
			}
		}
		if( segNum == length - 1 )
		{
			return SegmentType.STERN;
		}
		if( segNum > 0 && segNum < length )
		{
			return SegmentType.MID;
		}
		return SegmentType.NONE;
	}
	
	public int getShipCellNumber( int segNum, int boardWidth ){
		return ( getRow(segNum)*boardWidth + getCol(segNum) );
	}
		
	// Segment sub-Class.  Ship composed of multiple Segments
	public class Segment {
		boolean damaged;
		public int rowLocation;
		public int colLocation;
		SegmentType type;

		// Default Constructor
		public Segment( int row , int col ) {
			rowLocation = row;
			colLocation = col;
			damaged = false;
		}
		
		// Returns whether Segment matches specified coordinates
		private boolean isMatch ( int row , int col ) {
			if( row == rowLocation && col == colLocation )
			{
				return true;
			}
			return false;
		}

		// Checks segment's damage value
		public boolean isHit() {
			return damaged;
		}
			
		// Sets segement's damage value;
		public void setHit() {
			damaged = true;
		}
	}
}
